<template>
    <div class="chart-wrapper">
      <div id="chart" ref="chartContainer"></div>
    </div>
</template>
  
<script setup lang="ts" name="RingChart">
    import { computed, onMounted, onUnmounted, reactive, ref, watch } from "vue";
    import * as echarts from "echarts";
    import "echarts/lib/component/grid";
    import 'echarts/lib/chart/line';
    import {filterLabel, filterEmphasis} from '@/common/util'
    
    let chart: echarts.ECharts | null = null; // 声明图表实例
    const chartContainer = ref(null);
    const props = defineProps(['innerData', 'outerData', 'middleData', 'globalStart', 'globalEnd', 'totalMid'])

    const innerLevels = [
        { r0: "0%", r: "10%", intr: 0.2},
        { r0: "15%", r: "30%", intr: 0.3, gapWidth: 6 },
    ]

    const midLevels = [
        { r0: "45%", r: "60%", intr: 0.45, gapWidth: 6 },
        { r0: "60%", r: "75%", intr: 0.6, gapWidth: 6 },
    ]

    const outerLevels = [
        { r0: "70%", r: "80%" },
        { r0: "85%", r: "100%" },
    ]

    // 将一个数值映射到 [0,360] 的角度
    function toAngle(x: number) {
        return ((x - props.globalStart) / (props.globalEnd - props.globalStart)) * 360
    }

    function getCNRing() {
        const base = 20; // 基准半径
        const amp = 30;  // 振幅
        const allCNs = props.outerData.flatMap((seg:any) => seg.cnList);
        
        const maxCN = Math.max(...allCNs, 1); // 防止除零

        return props.outerData.map((seg: any, idx: number) => {
            const cnList = seg.cnList;
            const maxIdx = cnList.indexOf(Math.max(...cnList));
            const minIdx = cnList.indexOf(Math.min(...cnList));

            const data = cnList.map((cn: any, i: number) => {
                const globalPos = seg.coordList[i];
                const angle = toAngle(globalPos);
                const r = base + (cn / maxCN) * amp

                return {
                    value: [r, angle],
                    label: {
                        // show: props.outerData.length <= 5 && (i === maxIdx || i === minIdx),
                        show: false,
                        position: 'outside',
                        distance: 10,
                        formatter: i === maxIdx
                        ? `CN Max: ${cn.toFixed(2)}`
                        : i === minIdx
                            ? `CN Min: ${cn.toFixed(2)}`
                            : '',
                        fontSize: 12,
                        color: '#333'
                    }
                };
            });

            // baseData，顺序反过来拼接，形成封闭路径
            const baseData = seg.coordList.map((globalPos: any) => {
                const angle = toAngle(globalPos);
                return [base, angle];
            }).reverse();

            const polygonData = [...data, ...baseData];

            return {
                name: seg.name || `Outer ${idx + 1}`,
                type: 'line',
                coordinateSystem: 'polar',
                data: polygonData,
                showSymbol: true, // 必须 true，label 才能显示
                symbol: 'dot',    // 👈 不显示拐点
                symbolSize: 0.1,
                lineStyle: {
                    width: 2,
                    color: seg.color || '#5470c6'
                },
                areaStyle: {
                    color: seg.color || '#5470c6',
                    opacity: 1
                },
                smooth: true
            };
        });
    }


    function generateSunburstSeries(data: any[], r0: string, r1: string, levels: any[], showLabel: boolean) {
        return {
            type: "sunburst",
            data,
            radius: [r0, r1],
            sort: null,
            // minAngle: 5, 后端代码强行控制
            label: {
                show: showLabel,
                rotate: '0',
                position: 'inside',
                formatter: filterLabel,
                rich: {
                    name: {
                        fontSize: 12,
                        color: 'black',
                        align: 'center'
                    }
                },
            },
            labelLayout: {
                hideOverlap: true
            },
            emphasis: {
                label: {
                    show: true,
                    position: 'inside',
                    overflow: "break",
                    formatter: filterEmphasis,
                    rich: {
                        name: {
                            fontSize: 12,
                            color: 'black',
                            align: 'center'
                        },
                        range: {
                            fontSize: 10,
                            color: 'black',
                            align: 'center',
                            padding: [10, 0, 0, 0]
                        }
                    }
                }
            },
            itemStyle: { borderColor: "#fff", borderWidth: 10 },
            nodeClick: false,
            levels
        }
    }

    const updateChart = () => {
        if (!chart) return;

        let option = ref({
            polar: {
                radius: ['0%', '100%'],
            },
            angleAxis: {
                type: 'value',
                startAngle: 90,
                clockwise: true,
                min: 0,
                max: 360,
                show: false,
            },
            radiusAxis: {
                type: 'value',
                min: 0,
                max: 100,
                show: false,
            },
            series: [
                generateSunburstSeries(props.innerData, '0%',  '35%', outerLevels, true),
                generateSunburstSeries(props.middleData, '35%','65%', midLevels, true),
                // generateSunburstSeries(props.outerData, '65%','100%', outerLevels, true),
                ...getCNRing(),
                // getCustomSeries.value
            ],
        })
        chart.setOption(option.value); // 更新图表的配置
    };

    const highlightState = reactive({
        type: '', // 'Start' 或 'End'
        value: null // 对应的 start/end 值
    })


    const getCustomSeries = computed(() => ({
        type: 'custom',
        coordinateSystem: 'polar',
        renderItem: function (params: any, api: any) {
            const innerRadiusInner = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.35 * innerLevels[0]['intr']
            const middleRadiusOuter = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.35 * midLevels[1]['intr'] - 5

            const globalStart = props.globalStart
            const globalEnd = props.globalEnd
            const totalValue = props.totalMid

            const lines = props.middleData.flatMap((item: any) => {
                // === 跳过占位段 ===
                if (!item.name || (item.itemStyle && item.itemStyle.opacity === 0)) {
                    return [];
                }

                const angleStart = ((item.renderStart - globalStart) / totalValue) * 360;
                const angleEnd = ((item.renderEnd - globalStart) / totalValue) * 360;

                const pStart1 = api.coord([innerRadiusInner, angleStart]);
                const pStart2 = api.coord([middleRadiusOuter, angleStart]);
                const pEnd1 = api.coord([innerRadiusInner, angleEnd]);
                const pEnd2 = api.coord([middleRadiusOuter, angleEnd]);
                // 判断当前线段是否应该高亮
                const isStartHighlighted = 
                    highlightState.type === 'Start' && 
                    highlightState.value === item.start;
                
                const isEndHighlighted = 
                    highlightState.type === 'End' && 
                    highlightState.value === item.end;

                return [
                    {
                        type: 'line',
                        shape: {
                            x1: pStart1[0],
                            y1: pStart1[1],
                            x2: pStart2[0],
                            y2: pStart2[1],
                        },
                        style: { 
                            stroke: isStartHighlighted ? '#000' : '#e2e6ec', 
                            lineWidth: isStartHighlighted ? 2 : 1.5 
                        },
                        emphasis: { 
                            style: { 
                            stroke: '#000', 
                            lineWidth: 2 
                            },
                        },
                        textContent: {
                            type: 'text',
                            style: {
                                text: `Start:${item.start}`,
                                fill: '#000',
                                font: '12px sans-serif',
                                opacity: isStartHighlighted ? 1 : 0
                            },
                        },
                        textConfig: {
                            position: "inside",
                        },
                        info: {
                            name: item.name,
                            type: 'Start',
                            value: item.start
                        },
                    },
                    {
                        type: 'line',
                        shape: {
                            x1: pEnd1[0],
                            y1: pEnd1[1],
                            x2: pEnd2[0],
                            y2: pEnd2[1],
                        },
                        style: { 
                            stroke: isEndHighlighted ? '#000' : '#e2e6ec', 
                            lineWidth: isEndHighlighted ? 2 : 1.5 
                        },
                        emphasis: { 
                            style: { 
                            stroke: '#000', 
                            lineWidth: 2 
                            },
                        },
                        textContent: {
                            type: 'text',
                            style: {
                                text: `End:${item.end}`,
                                fill: '#000',
                                font: '12px sans-serif',
                                opacity: isEndHighlighted ? 1 : 0
                            },
                        },
                        textConfig: {
                            position: "inside",
                        },
                        info: {
                            name: item.name,
                            type: 'End',
                            value: item.end
                        },
                    },
                ];
            });

            return {
                type: 'group',
                children: lines,
            }
        },
        data: [{}],
        z: 100,
    }))

    // 监听高亮状态变化
    watch(highlightState, () => {
        updateChart()
    })

    watch([() => props.innerData, () => props.outerData, () => props.middleData,], updateChart, { deep: true });

    onMounted(() => {
        chart = echarts.init(chartContainer.value); // 初始化图表
        updateChart(); // 初始化时设置图表的配置

        // 修改鼠标事件处理
        chart.on('mouseover', function (params: any) {
            if (params.componentSubType === 'custom' && params.info) {
                highlightState.type = params.info.type
                highlightState.value = params.info.value
            }
        })

        chart.on('mouseout', () => {
            highlightState.type = ''
            highlightState.value = null
        })
    });

    onUnmounted(() => {
        if (chart) {
            chart.dispose()
            chart = null
        }
    })

                
</script>
  
<style scoped>
    .chart-wrapper {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%; /* 让容器占满 */
        height: 80vh; /* 或者指定高度 */
    }

    #chart {
        width: 100%;
        height: 600px;
    }
</style>